package bankrmi;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;


/**
 * Applications r�parties
 * TP 3
 * Gestion de comptes bancaires, Java RMI
 * 
 * Client d'une agence de la banque
 * 
 * @author Toto
 * @version 1.0
 */
public class BankClientRMI {

	/**
	 * Nom par d�faut de la machine o� tourne le registre RMI
	 */
	private static String DEFAULT_HOST = "localhost";

	/**
	 * Port par d�faut du registre RMI distant
	 */
	private static int DEFAULT_REGISTRY_PORT = 1099;


	/**
	 * M�thode utilitaire de saisie du nom d'un compte
	 * @param in Flux d'entr�e (clavier)
	 * @return String Nom du compte
	 * @throws IOException 
	 */
	public static String getName(BufferedReader in) 
	throws IOException {
		String name = null;
		System.out.print("Nom du compte : ");
		name = in.readLine();
		return name;
	}

	/**
	 * M�thode utilitaire de saisie d'un mot de passe
	 * @param in Flux d'entr�e (clavier)
	 * @return String Mot de passe du compte
	 * @throws IOException
	 */
	public static String getPassword(BufferedReader in)
	throws IOException {
		String password = null;
		System.out.print("Mot de passe : ");
		password = in.readLine();
		return password;
	}

	/**
	 * M�thode de r�cup�ration du code op�ration
	 * @param op Code op�ration (sous forme d'une String)
	 * @return int Code op�ration
	 * @throws NumberFormatException
	 */
	public static int getOperation(String op) throws NumberFormatException{
		int operation = -1;
		operation = Integer.parseInt(op);
		return operation;
	}

	/**
	 * M�thode de r�cup�ration du montant de l'op�ration
	 * @param in Flux d'entr�e (clavier)
	 * @return int Montant saisi
	 * @throws IOException, NumberFormatException
	 */
	public static float getAmount(BufferedReader in)
	throws IOException, NumberFormatException {
		float amount = -1f;
		System.out.print("Montant : ");
		amount = Float.parseFloat(in.readLine());
		return amount;
	}

	/**
	 * Affichage du menu.
	 */
	public static void displayMenu() {
		System.out.println("\n****** Menu ******");
		System.out.println("Choix op�ration :");
		System.out.println(BankUtil.OPEN+" - Ouverture");
		System.out.println(BankUtil.CLOSE+" - Fermeture");
		System.out.println(BankUtil.DEPOSIT+" - D�pot");
		System.out.println(BankUtil.WITHDRAW+" - Retrait");
		System.out.println(BankUtil.BALANCE+" - Consultation solde");
		System.out.println("quit - Quitter");
		System.out.print("> ");
	}



	/**
	 * Programme principal (les arguments sont optionnels)
	 * @param args[0] Nom du serveur
	 * @param args[1] Port du serveur
	 */
	public static void main(String[] args) {
		BufferedReader userInput = null;
		String theLine = null;
		String server = null;
		int port = -1;
		int operation = -1;
		String name = null;
		String password = null;
		float amount = -1f;
		float response = 0f;

		if(args.length != 2) {
			System.out.println("Usage: java tp3.BankClientRMI NomServeur PortServeur");
			System.out.println("Utilisation du nom de serveur et du port par d�faut ("+BankClientRMI.DEFAULT_HOST+":"+BankClientRMI.DEFAULT_REGISTRY_PORT+")");
			server = BankClientRMI.DEFAULT_HOST;
			port = BankClientRMI.DEFAULT_REGISTRY_PORT;
		}
		else {
			try {
				server = args[0];
				port = Integer.parseInt(args[1]);
			}
			catch(NumberFormatException nfe) {
				nfe.printStackTrace();
				System.exit(1);
			}
		}

		try {
			userInput = new BufferedReader(new InputStreamReader(System.in));

			System.setSecurityManager(new RMISecurityManager()); 
			BankInterface allAccounts = (BankInterface) Naming.lookup("rmi://"+server+":"+port+"/Comptes");

			while(true) { 
				displayMenu();

				theLine = userInput.readLine();

				if(theLine.equals("quit")) { 
					System.out.println("Au revoir."); 
					break;
				}

				try {
					operation = getOperation(theLine);
					name = getName(userInput);
					password = getPassword(userInput);

					if(operation == BankUtil.DEPOSIT || operation == BankUtil.WITHDRAW) {	
						amount = getAmount(userInput);
					}


					switch(operation) {
					case BankUtil.OPEN : 
						response = allAccounts.openAccount(name, password);
						break;
					case BankUtil.CLOSE :
						response = allAccounts.closeAccount(name, password);
						break;
					case BankUtil.DEPOSIT :
						response = allAccounts.deposit(name, password, amount);
						break;
					case BankUtil.WITHDRAW :
						response = allAccounts.withdraw(name, password, amount);
						break;
					case BankUtil.BALANCE :
						response = allAccounts.getBalance(name, password);
						break;
					}

					System.out.println(response);
				}
				catch (BankException be) {
					System.err.println("Erreur : "+be);
					continue;
				}
				catch(NumberFormatException nfe) {
					System.err.println("Erreur : mauvais code op�ration\n"+nfe.getMessage());
					continue;
				}

			}
		}
		catch (IOException ioe) { 
			System.err.println("Erreur : "+ioe);
			ioe.printStackTrace();
		}
		catch (NotBoundException nbe) {
			System.err.println("Erreur : "+nbe);
			nbe.printStackTrace();
		}
	}

}
